package codegen.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;

import java.io.InputStream;
import java.util.Map;

/**
 * 配置类，用于加载和管理项目配置信息
 * 采用单例模式，确保全局配置唯一性
 * 配置文件位置：src/main/resources/config.json
 */
@Data
public class Configuration {
    /** 项目基本信息配置 */
    private ProjectConfig project;
    /** 代码生成相关配置 */
    private GenerationConfig generation;

    /**
     * 项目基本信息配置类
     */
    @Data
    public static class ProjectConfig {
        /** 项目名称 */
        private String name;
        /** 项目版本号 */
        private String version;
        /** 项目描述 */
        private String description;
        /** 项目作者 */
        private String author;
        /** 项目基础包名 */
        private String packageName;
    }

    /**
     * 代码生成相关配置类
     */
    @Data
    public static class GenerationConfig {
        /** 模板文件所在目录 */
        private String templatePath;
        /** 生成的代码输出目录 */
        private String outputPath;
        /** 数据库连接配置 */
        private DatabaseConfig database;
        /** 代码模板配置映射，key为模板类型，value为具体配置 */
        private Map<String, TemplateConfig> templates;
    }

    /**
     * 数据库连接配置类
     */
    @Data
    public static class DatabaseConfig {
        /** 数据库类型(mysql/postgresql/oracle等) */
        private String type;
        /** 数据库主机地址 */
        private String host;
        /** 数据库端口号 */
        private int port;
        /** 数据库用户名 */
        private String username;
        /** 数据库密码 */
        private String password;
        /** 数据库名称 */
        private String database;
    }

    /**
     * 代码模板配置类
     */
    @Data
    public static class TemplateConfig {
        /** 使用的模板文件名 */
        private String template;
        /** 生成文件的输出目录 */
        private String outputPath;
        /** 生成的文件名格式，支持变量替换，例如：${className}.java */
        private String fileNameFormat;
    }

    /** 单例实例 */
    private static Configuration instance;

    /**
     * 获取配置实例
     * 采用单例模式，确保全局配置唯一性
     *
     * @return Configuration实例
     */
    public static Configuration getInstance() {
        if (instance == null) {
            instance = loadConfiguration();
        }
        return instance;
    }

    /**
     * 加载配置文件
     * 从classpath下的config.json文件中加载配置信息
     *
     * @return 加载的配置实例
     * @throws RuntimeException 当配置文件加载失败时抛出
     */
    private static Configuration loadConfiguration() {
        try {
            ObjectMapper mapper = new ObjectMapper();
            InputStream is = Configuration.class.getClassLoader().getResourceAsStream("config.json");
            return mapper.readValue(is, Configuration.class);
        } catch (Exception e) {
            throw new RuntimeException("Failed to load configuration", e);
        }
    }
}
